package com.lzx.adx.report.support.strategy.v2.media;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.lzs.adx.commmon.enums.ReportEnums;
import com.lzs.adx.commmon.utils.DateUtils;
import com.lzs.adx.commmon.utils.Result;
import com.lzs.adx.commmon.utils.SpringContextUtils;
import com.lzx.adx.report.constant.StatusConstant;
import com.lzx.adx.report.dto.AccountDTO;
import com.lzx.adx.report.dto.ReportDTO;
import com.lzx.adx.report.dto.ResultTypeDTO;
import com.lzx.adx.report.service.AccountService;
import com.lzx.adx.report.service.BackDataService;
import com.lzx.adx.report.service.ReportService;
import com.lzx.adx.report.service.ResultTypeService;
import com.lzx.adx.report.util.AdPerUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
public abstract class AbstractCallback {

    /**
     * 通用的可回传功能
     * @param per
     * @return
     */
    public  boolean shouldIdentifyAd(Double per) {
        Random random = new Random();
        double randomValue = random.nextDouble(); // 生成到1之间的随机数
        log.info("随机数为{}", randomValue);
        return randomValue > per;
    }




    public boolean base(ReportDTO reportDTO, AccountDTO accountDTO,String callType,String time) {
        ReportService reportService = SpringContextUtils.getBean(ReportService.class);

        //2.从缓存加载配置
        reportDTO.setResultType(callType);
        reportDTO.setResultTime(time);
        reportDTO.setUpdateTime(new Date());
        reportService.updateData(reportDTO,callType);


        String sspExtend = accountDTO.getSspExtend();
        JSONObject jsonObject = JSONObject.parseObject(sspExtend);
        String event_type = jsonObject.getString(callType);
        String requestId = reportDTO.getBizRequestId();

        //检查总转化量控制的限制
        if (checkTotalLimit(accountDTO, callType,  requestId)){
            return false;
        }
        //检查总当日转化量控制的限制
        if (checkCurrentDayLimit(accountDTO, callType,  requestId)){
            return false;
        }


        if (StringUtils.isBlank(event_type)){
            log.info("账户{}接收了产品段的回调信息当前流水号：{}，事件类型{}不合法，不做数据回传",accountDTO.getId(), requestId,callType);
            return false;
        }


        Double per = jsonObject.getDouble("per");
        if (Objects.nonNull(per)) {
            if (!AdPerUtil.randomPer(per)) {
                log.info("账户{}流水号{}超出了比例,不做回传", reportDTO.getDspId(), reportDTO.getBizRequestId());
                return false;
            }
        }
        return true;
    }

    /**
     * 检查总转化量控制的限制
     * @param accountDTO
     * @param callType

     * @param requestId
     * @return
     */
    private static boolean checkTotalLimit(AccountDTO accountDTO, String callType,  String requestId) {
        BackDataService backDataService = SpringContextUtils.getBean(BackDataService.class);
        ResultTypeService resultTypeService = SpringContextUtils.getBean(ResultTypeService.class);
        AccountService accountService = SpringContextUtils.getBean(AccountService.class);
        if(Objects.nonNull(accountDTO.getTotalLimitNumber()) && accountDTO.getTotalLimitNumber()>0){
            Map<String,Object> params = new HashMap<>();
            params.put("productChannle", accountDTO.getProductChannel());
            params.put("resultType", callType);
            List<ResultTypeDTO> list = resultTypeService.list(params);
            if(CollectionUtil.isEmpty(list)){
                log.error("账户号{},未配置转化类型{}", accountDTO.getId(), callType);
            }else{
                ResultTypeDTO resultTypeDTO = list.get(0);
                if(accountDTO.getKeyType().equals(ReportEnums.getKey(resultTypeDTO.getType()))){
                    long total = backDataService.countTotal(accountDTO.getId(), callType);
                    if(total>= accountDTO.getTotalLimitNumber()){
                        log.info("账户{}流水号{}超出了转化总量限制，不做回传,转化类型{}", accountDTO.getId(), requestId, callType);
                        //更新账户的状态
                        accountDTO.setStatus(StatusConstant.DISABLE);
                        accountService.update(accountDTO);
                        accountService.sysnCacheToDb();
                        return true;
                    }
                }else{
                    log.info("账户号{},转化类型{}，非关键指标，不做限制处理");
                }
            }
        }
        return false;
    }



    /**
     * 检查总转化量控制的限制
     * @param accountDTO
     * @param callType
     * @param requestId
     * @return
     */
    private static boolean checkCurrentDayLimit(AccountDTO accountDTO, String callType,  String requestId) {
        BackDataService backDataService = SpringContextUtils.getBean(BackDataService.class);
        ResultTypeService resultTypeService = SpringContextUtils.getBean(ResultTypeService.class);
        AccountService accountService = SpringContextUtils.getBean(AccountService.class);
        if(Objects.nonNull(accountDTO.getDayLimitNumber()) && accountDTO.getDayLimitNumber()>0){
            Map<String,Object> params = new HashMap<>();
            params.put("productChannle", accountDTO.getProductChannel());
            params.put("resultType", callType);
            List<ResultTypeDTO> list = resultTypeService.list(params);
            if(CollectionUtil.isEmpty(list)){
                log.error("账户号{},未配置转化类型{}", accountDTO.getId(), callType);
            }else{
                ResultTypeDTO resultTypeDTO = list.get(0);
                if(accountDTO.getKeyType().equals(ReportEnums.getKey(resultTypeDTO.getType()))){
                    long total = backDataService.countCurrentDayTotal(accountDTO.getId(), callType, DateUtils.getCurrentTime());
                    if(total>= accountDTO.getDayLimitNumber()){
                        log.info("账户{}流水号{}超出了当日转化总量限制，不做回传,转化类型{}", accountDTO.getId(), requestId, callType);
                         if(!accountDTO.getStatus().equals(StatusConstant.NUMBER_LIMITER)){
                             //更新账户的状态
                             accountDTO.setStatus(StatusConstant.NUMBER_LIMITER);
                             accountService.update(accountDTO);
                             accountService.sysnCacheToDb();
                         }
                         return true;
                    }
                }else{
                    log.info("账户号{},转化类型{}，非关键指标，不做限制处理");
                }
            }
        }
        return false;
    }


    public abstract ResponseEntity callback(ReportDTO reportDTO, AccountDTO accountDTO,String callType,String ts);

}
